// Copyright (c) 2010 Omer Goshen
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef __COMPONENT_H__
#define __COMPONENT_H__

#include <iostream>
#include <typeinfo>
#include <string>

#include <Ogre.h>

#include "core/Countable.h"

using namespace Ogre;

class ComponentContainer;

class Component : public Countable<Component>
{
	friend class ComponentContainer;
	friend class IComponentCreator;
public:
	Component() : mId(howMany()), mName(toString()+StringConverter::toString(mId)) {};
	Component(const Ogre::String &name) : mId(howMany()), mName(name) {};
	Component(ComponentContainer* c) : mId(howMany()), mContainer(c) { assert(c); };
	Component(ComponentContainer* c, const Ogre::String &name) : mId(howMany()), mName(name), mContainer(c) { assert(c); };
	virtual ~Component() {};

	virtual const size_t 		 getId(void)   const { return mId; }
	virtual const Ogre::String&  getName(void) const { return mName; }

	virtual std::string			 toString(void) const { return "Component"; }
	
	friend std::ostream& operator<<(std::ostream& stream, Component comp)
	{
		return stream << comp.toString() << "::" << comp.getName();
	}

	inline void _setContainer(ComponentContainer* c) { mContainer = c; }

protected:
	const size_t mId;
	Ogre::String mName;

	ComponentContainer* mContainer;

};

#endif
